<?php

 /**
 * ACoreNetSocket
 *
 * @author Usenko Timur <usenko.timur@gmail.com>
 * @package net
 */

CCore::Using('base.object');
CCore::Using('net.constants');

/**
 * @package net
 */
abstract class ACoreNetAbstract extends ACoreBaseObject
{
	#<editor-fold defaultstate="collapsed" desc="protected">
	/**
	 * @var ACoreNetConfig
	 */
	protected $oConfig;

	/**
	 * @var resource
	 */
	protected $rConnect;
 	#</editor-fold>

	/**
	 * @param ACoreNetConfig $oSocketConfig
	 * @return ACoreNetAbstract
	 */
	public function __construct(ACoreNetConfig $oSocketConfig)
	{
		CCore::CheckTypes(array('$oSocketConfig'));

		parent::__construct();

		$this->oFollowers->InitPrefixs('Socket', 'Socket[Error]', 'Socket[Warning]', 'Socket[Notice]');

		$this->oConfig = $oSocketConfig;
	}

	/**
	 * @return bool
	 */
	public function Connect($bIsSSL = false)
	{
		CCore::CheckTypes(array('$bIsSSL'));

		if ($this->IsConnected())
		{
			$this->oFollowers->Write('connection also avalible.', CCoreBaseFollowersCollection::WARNING);
			$this->Disconnect();
			return false;
		}

		$sErrorStr = '';
		$iErrorNo = 0;

		$sHost = $this->oConfig->GetValue('Host', 'string');
		$iPort = $this->oConfig->GetValue('Port', 'int');
		$iConnectTimeOut = $this->oConfig->GetValue('ConnectTimeOut', 'int');
		$iSocketTimeOut = $this->oConfig->GetValue('SocketTimeOut', 'int');

		$sHost = ($bIsSSL) ? 'ssl://'.$sHost : $sHost;

		$this->oFollowers->Write('start connect to '.$sHost.':'.$iPort, CCoreBaseFollowersCollection::INFO);
		$this->rConnect = @fsockopen($sHost, $iPort, $iErrorNo, $sErrorStr, $iConnectTimeOut);

		if (!$this->IsConnected())
		{
			$this->oFollowers->Write('can\'t connect to server '.$sHost.':'.$iPort,
				CCoreBaseFollowersCollection::WARNING);
			$this->oFollowers->Write('['.$iErrorNo.'] '.$sErrorStr,
					CCoreBaseFollowersCollection::WARNING);

			return false;
		}

		@stream_set_timeout($this->rConnect, $iSocketTimeOut);
		@stream_set_blocking($this->rConnect, true);
		return true;
	}

	/**
	 * @return bool
	 */
	public function Disconnect()
	{
		if ($this->IsConnected())
		{
			@fclose($this->rConnect);
		}
		return true;
	}

	/**
	 * @return bool
	 */
	public function IsConnected()
	{
		return is_resource($this->rConnect);
	}
}
